#include "TutorApp4.h"

#ifdef WIN32
#ifdef Tutorial4_EXPORTS
#define TUTORAPP4_API __declspec(dllexport)
#else
#define TUTORAPP4_API __declspec(dllimport)
#endif
#else
#define TUTORAPP4_API
#endif

extern "C" TUTORAPP4_API Blobz::BaseApplication* GetInstance()
{
	Tutorial4::TutorApp4* pTutorial = new Tutorial4::TutorApp4();
	return (Blobz::BaseApplication*)pTutorial;
}

extern "C" TUTORAPP4_API unsigned int GetMajorReleaseVersion()
{
	return NUI_RELEASE_MAJOR_VER;
}

extern "C" TUTORAPP4_API unsigned int GetMinorReleaseVersion()
{
	return NUI_RELEASE_MINOR_VER;
}

extern "C" TUTORAPP4_API const char* GetAppName()
{
	return "Tutorial4";
}

namespace Tutorial4
{
	/**
	* Constructor
	*/
	TutorApp4::TutorApp4() :
		mpPreviousButton(NULL),
		mpRefreshButton(NULL),
		mpNextButton(NULL)
	{
		getWindow().setTitle("Tutorial 4");
	}

	/**
	* Destructor
	*/
	TutorApp4::~TutorApp4()
	{
	}

	/**
	* Loads and setups up all the required objects and gui elements
	*/
	bool TutorApp4::onInitialize()
	{
		// Tell the application to use a fixed aspect ratio so that our view content is not stretched
		getWindow().setUseFixedRatio(true);

		// Save the application directory for easier access
		QString appDir = getApplicationDirectory();

		// save the application window aspect ratio
		float aspectRatio = getWindow().getWindowAspect();

		// load the background texture
		mBackgroundTexture.load(appDir+"bg.png", true);

		// load menu buttons
		mpPreviousButton = mMenuManager.addButton("PreviousButton", appDir+"prev.png", "");
		mpRefreshButton = mMenuManager.addButton("RefreshButton", appDir+"refresh.png", "");
		mpNextButton = mMenuManager.addButton("NextButton", appDir+"next.png", "");

		// setup menu buttons size and position
		QVector2D buttonSize = QVector2D(0.1f, 0.1f);
		mpPreviousButton->setSize(buttonSize);
		mpRefreshButton->setSize(buttonSize);
		mpNextButton->setSize(buttonSize);

		mpRefreshButton->setPosition(QVector2D(aspectRatio*0.5f, buttonSize.y()*0.5f));
		mpPreviousButton->setPosition(mpRefreshButton->getPosition()-QVector2D(buttonSize.x()*1.5f, 0.0f));
		mpNextButton->setPosition(mpRefreshButton->getPosition()+QVector2D(buttonSize.x()*1.5f, 0.0f));

		// add our app as a listener for gui events
		mMenuManager.addListener(this);

		// load the pdf
		mPDF.setPosition(QVector2D(aspectRatio*0.5f, 0.5f)); //set the position of the pdf to the center of the screen
		mPDF.setScale(0.75f);
		mPDF.setScaleLimits(0.075f, 7.5f);
		mPDF.load(appDir, appDir+"example.pdf");

		return true;
	}

	/**
	* On Reload Handler
	*/
	void TutorApp4::onReload()
	{
	}

	/**
	* Unload all loaded objects
	*/
	void TutorApp4::onDeinitialize()
	{
		// unload all objects
		mBackgroundTexture.unload();
		mMenuManager.unload();
		mPDF.unload();
	}

	/**
	* Update event handler
	*/
	void TutorApp4::onUpdate(float inFrameTime)
	{
		// send update events to all objects
		mMenuManager.update(inFrameTime);
		mPDF.onUpdate(inFrameTime);

		if(mPDF.getPosition().x() < 0)
			mPDF.setPosX(0);
		else if(mPDF.getPosition().x() > getWindow().getWindowAspect())
			mPDF.setPosX(getWindow().getWindowAspect());
		if(mPDF.getPosition().y() < 0)
			mPDF.setPosY(0);
		else if(mPDF.getPosition().y() > 1)
			mPDF.setPosY(1);
	}

	/**
	* Render event handler
	*/
	void TutorApp4::onDraw()
	{
		// tell Snowflake that we want to start rendering
		getWindow().enableRendering();

		// screen setup, part of the Snowflake framework
		// clears the background to white
		getWindow().defaultRenderSetup(QVector4D(1,1,1,1));

		// Render the background texture
		const QVector2D windowSize(getWindow().getWindowAspect(), 1.0f);
		const QVector2D mPosition(0.0f, 0.0f);

		// Enables alpha blending
		glEnable(GL_BLEND);
		glDisable(GL_DEPTH_TEST);
		glEnable(GL_TEXTURE_2D);

		// Binds the texture ID to OpenGL so it can be used
		glBindTexture(GL_TEXTURE_2D, mBackgroundTexture.getID());
		// Begin drawing GLQuads
		glBegin(GL_QUADS);
		glColor4f(1, 1, 1, 1);
		glTexCoord2f(0,1);
		glVertex2f(mPosition.x(), mPosition.y());
		glTexCoord2f(1,1);
		glVertex2f(mPosition.x()+windowSize.x(), mPosition.y());
		glTexCoord2f(1,0);
		glVertex2f(mPosition.x()+windowSize.x(), mPosition.y()+windowSize.y());
		glTexCoord2f(0,0);
		glVertex2f(mPosition.x(), mPosition.y()+windowSize.y());
		glEnd();
		glDisable(GL_TEXTURE_2D);

		// render the pdf
		mPDF.onRender();

		// render the menu over the pdf
		mMenuManager.render();

		// tell Snowflake that we're done rendering
		getWindow().disableRendering();
	}

	/**
	* Triggered when there is a finger down event on the screen
	* \param inData holds the touch information
	*/
	void TutorApp4::onFingerDown(const TouchListener::TouchData& inData)
	{
		// first send the finger down events to the menu overlay
		// mMenuManager.onFingerDown(inData) returns true if the touch event was handled by the gui
		if(mMenuManager.onFingerDown(inData))
			return;

		// if the menu doesn't handle the touch event then pass it to the pdf object
		mPDF.onFingerDown(inData);
	}

	/**
	* Triggered when there is a finger up event on the screen
	* \param inData holds the touch information
	*/
	void TutorApp4::onFingerUp(const TouchListener::TouchData& inData)
	{
		// first send the finger up events to the menu overlay
		// mMenuManager.onFingerUp(inData) returns true if the touch event was handled by the gui
		if(mMenuManager.onFingerUp(inData))
			return;

		// if the menu doesn't handle the touch event then pass it to the pdf object
		mPDF.onFingerUp(inData);
	}

	/**
	* Triggered when there is a finger update event on the screen
	* \param inData holds the touch information
	*/
	void TutorApp4::onFingerUpdate(const TouchListener::TouchData& inData)
	{
		// first send the finger update events to the menu overlay
		// mMenuManager.onFingerUpdate(inData) returns true if the touch event was handled by the gui
		if(mMenuManager.onFingerUpdate(inData))
			return;

		// if the menu doesnt handle the touch event then pass it to the pdf object
		mPDF.onFingerUpdate(inData);
	}

	/**
	* Triggered when there is a finger moves out of the screen or application window
	* \param inData holds the touch information
	*/
	void TutorApp4::onFingerExit(const TouchListener::TouchData& inData)
	{
		// just treat finger exit events as finger up events
		onFingerUp(inData);
	}

	/**
	* Triggered when there is a GUI event from the GUIManager that the application is listening to
	* \param inpComponent A pointer to the GUI component
	* \param inGUIEvent The GUI event type
	* \param inFingerEvent The finger event (up/down/update) associated with the GUI event
	*/
	void TutorApp4::onGUIEvent(Blobz::GUIBase* inpComponent, Blobz::GUIEvent inGUIEvent, Blobz::FingerEvent inFingerEvent)
	{
		// check if the event is caused by a button being released
		if(inGUIEvent == Blobz::Button_Released)
		{
			// compare the GUI component pointer to our button pointers
			if(inpComponent == mpPreviousButton)
			{
				// go to the previous page
				mPDF.previousPage();
			}
			else if(inpComponent == mpNextButton)
			{
				// go to the next page
				mPDF.nextPage();
			}
			else if(inpComponent == mpRefreshButton)
			{
				// reset the pdf
				mPDF.reset();
				mPDF.setPosition(QVector2D(getWindow().getWindowAspect()*0.5f, 0.5f));
				mPDF.setScale(0.75f);
			}
		}
	}
}
